package com.rockbb.common.simpleapp;

import java.util.List;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

public abstract class ExecutorBasic extends TimerTask 
{
	private static Logger logger = Logger.getLogger(ExecutorBasic.class);

	private int executor_size;
	private int init;
	private String name_prefix;

	/**
	 * 初始化一个指定大小的执行绪池: 数量4, 前缀executor
	 */
	public ExecutorBasic() 
	{
		this.executor_size = 4;
		this.name_prefix = "executor";
		this.init = 0;
	}

	/**
	 *  用于初始化一个指定大小的执行绪池的参数
	 *  
	 * @param prefix 名称前缀
	 * @param size 执行绪数量
	 * @param init 执行绪编号初始值
	 */
	public ExecutorBasic(String prefix, int size, int init) 
	{
		this.executor_size = size;
		this.name_prefix = prefix;
		this.init = init;
	}

	public void run() 
	{
		if (executor_size == 0 || name_prefix == null) return;

		logger.info("Executor pool named "+name_prefix+" begins");
		ExecutorFactory executorfactory = new ExecutorFactory(name_prefix, init); 

		List<Thread> tasks = null;
		try
		{
			tasks = getThreadTasks();
		}
		catch(Exception e)
		{
			logger.error("Executor pool named "+name_prefix+" errors in getting tasks");
		}
		if (tasks == null || tasks.size() == 0) return;

		// Initialize the fixed thread executors pool
		ExecutorService pool = Executors.newFixedThreadPool(executor_size, executorfactory);

		// Put all task threads into the pool for process 
		for(int i=0; i<tasks.size(); i++) 
		{
			pool.execute(tasks.get(i));
			logger.info("Executor pool named "+name_prefix+" push task " + tasks.get(i).getName());
		}
		pool.shutdown();
		try 
		{
			// Block till all tasks have been done. It will wait 1 hour before time out
			boolean result = pool.awaitTermination(60*60, TimeUnit.SECONDS);
			if (result)
				logger.info("Executor pool named "+name_prefix+" ends");
			else
			{
				logger.info("Executor pool named "+name_prefix+" timeout elapsed");
				sendTimeoutAlert();
			}
		}
		catch(InterruptedException e)
		{
			logger.error("Executor pool named "+name_prefix+" broken on InterruptedException.");
		}
	}

	abstract protected List<Thread> getThreadTasks();
	abstract protected void sendTimeoutAlert();
}
